'use client';

import { useRouter } from 'next/navigation';
import { useContext, useEffect, useRef, useState } from 'react';
import {
  clientQueryUserDetails,
  logout,
  queryPostFavourites,
} from '@/services/api';
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
import type { IPost, IPostFavourite, IUserClientDetails } from '@/interfaces';
import classs from './userid.module.scss';
import classNames from 'classnames';
import Image from 'next/image';
import {
  formatCount,
  getUserAvatar,
  isHttpOrHttps,
  toRelativeTime,
} from '@/lib/tool';
import Link from 'next/link';
import useToast from '@/hooks/useToast';
import UpdatePasswordUserIdPage from '@/app/[locale]/users/[id]/password';
import UpdateBasicInfoUserIdPage from '@/app/[locale]/users/[id]/basicInfo';
import PostName from '@/app/[locale]/common/post/name';
import PostOverview from '@/app/[locale]/common/post/overview';
import PostReadMoreBtn from '@/app/[locale]/common/post/readMore';
import PostTime from '@/app/[locale]/common/post/time';
import type { IUserIdPageContext } from '@/contexts/user-id';
import { UserIdPageContext } from '@/contexts/user-id';
import { AppContext } from '@/contexts/app';
import PcBox from '@/app/[locale]/common/other/pc';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import UserIdH5Page from '@/app/[locale]/users/[id]/h5';

interface ITab {
  id:
    | 'myProfile'
    | 'editProfile'
    | 'chgPassword'
    | 'createPost'
    | 'myPosts'
    | 'myFavorites'
    | 'relContent'
    | 'relTags'
    | 'relStatistics'
    | 'editAvatar'
    | 'myApps'
    | 'logout';
  name: string;
  isLogin?: boolean;
  isMyHomePage?: boolean;
}

export default function UserIdPage(
  this: any,
  { source, translatedFields }: IUserIdPageContext,
) {
  const appContext = useContext(AppContext);
  const metadata = appContext.metadata!;
  const env = metadata.env;
  const router = useRouter();
  const myHomepageRef = useRef<HTMLDivElement>(null);
  const myPostRef = useRef<HTMLDivElement>(null);
  const myUpdatePasswordRef = useRef<HTMLDivElement>(null);
  const myUpdateBasicInfoRef = useRef<HTMLDivElement>(null);
  const myCollectionRef = useRef<HTMLDivElement>(null);
  const mySectionRef = useRef<HTMLDivElement>(null);
  const myTagRef = useRef<HTMLDivElement>(null);
  const myStatisticRef = useRef<HTMLDivElement>(null);
  const { show } = useToast();
  const [pages, setPages] = useState<IPost[]>(source.userDetails.data.content);
  const isLogin = !!source.path.user;
  const isMyHomePage = source.path.user?.id === source.userDetails.user.id;
  const tabs: ITab[] = [
    {
      id: 'myProfile',
      name: translatedFields.myProfile,
    },
    {
      id: 'editProfile',
      name: translatedFields.editProfile,
      isLogin,
      isMyHomePage,
    },
    {
      id: 'chgPassword',
      name: translatedFields.chgPassword,
      isLogin,
      isMyHomePage,
    },
    {
      id: 'createPost',
      name: translatedFields.createPost,
    },
    {
      id: 'myPosts',
      name: translatedFields.myPosts,
    },
    {
      id: 'myFavorites',
      name: translatedFields.myFavorites,
      isLogin,
      isMyHomePage,
    },
    {
      id: 'relContent',
      name: translatedFields.relContent,
    },
    {
      id: 'relTags',
      name: translatedFields.relTags,
    },
    {
      id: 'relStatistics',
      name: translatedFields.relStatistics,
    },
    {
      id: 'editAvatar',
      name: translatedFields.editAvatar,
      isLogin,
      isMyHomePage,
    },
    {
      id: 'myApps',
      name: translatedFields.myApps,
      isLogin,
      isMyHomePage,
    },
    {
      id: 'logout',
      name: translatedFields.logout,
      isLogin,
      isMyHomePage,
    },
  ];
  const roles = source.userDetails.user.roles.filter((item) => !item.hide);

  const logoutMutation = useMutation(logout);

  const clientQueryUserDetailsQuery = useInfiniteQuery(
    ['/users', '/client', source.userDetails.user.id, '/details', 'infinite'],
    async (context) => {
      return (await clientQueryUserDetails({
        id: context.queryKey[2],
        query: context.pageParam,
      })) as IUserClientDetails;
    },
    {
      keepPreviousData: true,
      getPreviousPageParam: (firstPage) => {
        if (!firstPage.data!.pageable.previous) {
          return;
        }
        return {
          page: Math.max(firstPage.data!.pageable.page - 1, 0),
        };
      },
      getNextPageParam: (lastPage) => {
        if (!lastPage.data!.pageable.next) {
          return;
        }
        return {
          page: Math.min(
            lastPage.data!.pageable.page + 1,
            lastPage.data!.pageable.pages,
          ),
        };
      },
      initialData: () => {
        return {
          pages: [source.userDetails],
          pageParams: [{ page: 0 }],
        };
      },
    },
  );
  const queryPostFavouritesQuery = useQuery(
    ['/forum', '/posts', '/favourites'],
    async () => {
      return (await queryPostFavourites()) as IPostFavourite[];
    },
    {
      enabled: isMyHomePage,
    },
  );

  useEffect(() => {
    if (clientQueryUserDetailsQuery.data) {
      setPages(
        clientQueryUserDetailsQuery.data.pages
          .flatMap((item) => item.data.content)
          .map((item) => {
            item._contentUpdatedOnText = toRelativeTime(item.contentUpdatedOn);
            return item;
          }),
      );
    }
  }, [clientQueryUserDetailsQuery.data]);

  async function onClickItem(item: ITab) {
    const id = item.id;
    if (id === 'myProfile') {
      myHomepageRef.current?.scrollIntoView();
    } else if (id === 'editProfile') {
      myUpdateBasicInfoRef.current?.scrollIntoView();
    } else if (id === 'chgPassword') {
      myUpdatePasswordRef.current?.scrollIntoView();
    } else if (id === 'createPost') {
      router.push('/posts/new');
    } else if (id === 'myPosts') {
      myPostRef.current?.scrollIntoView();
    } else if (id === 'myFavorites') {
      myCollectionRef.current?.scrollIntoView();
    } else if (id === 'relContent') {
      mySectionRef.current?.scrollIntoView();
    } else if (id === 'relTags') {
      myTagRef.current?.scrollIntoView();
    } else if (id === 'relStatistics') {
      myStatisticRef.current?.scrollIntoView();
    } else if (id === 'editAvatar') {
      router.push('/avatar');
    } else if (id === 'myApps') {
      router.push('/oauth/client');
    } else if (id === 'logout') {
      if (logoutMutation.isLoading) {
        return;
      }
      await onClickLogout();
    }
  }

  async function onClickLogout() {
    try {
      await logoutMutation.mutateAsync({});

      show({
        type: 'SUCCESS',
        message: translatedFields.logoutCompleted,
      });

      setTimeout(() => {
        show({
          type: 'INFO',
          message: translatedFields.reloading,
        });
      }, 1000);

      setTimeout(() => {
        location.reload();
      }, 1500);
    } catch (e) {
      logoutMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  async function onClickLoadMore() {
    try {
      await clientQueryUserDetailsQuery.fetchNextPage();
    } catch (e) {
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  return (
    <UserIdPageContext.Provider value={{ source, translatedFields }}>
      <PcBox classs="col px-2 py-4">
        <div
          className={classNames(
            'vh-100 position-fixed d-none d-md-block',
            classs.box,
          )}
        >
          <div className="vstack gap-4">
            {tabs.map((item) => {
              if (item.id === 'logout') {
                return (
                  <div
                    key={item.id}
                    onClick={onClickItem.bind(this, item)}
                    className={classNames(
                      'cursor-pointer hstack gap-2 me-4',
                      classs.item,
                    )}
                    style={{ width: 140 }}
                  >
                    <span className="text-start flex-grow-1">
                      {logoutMutation.isLoading
                        ? `${translatedFields.exitingNow}...`
                        : translatedFields.logout}
                    </span>
                    {logoutMutation.isLoading ? (
                      <span
                        className="spinner-border spinner-border-sm"
                        role="status"
                        aria-hidden="true"
                      ></span>
                    ) : (
                      <i className="bi bi-arrow-bar-right"></i>
                    )}
                  </div>
                );
              }

              return (
                <div
                  key={item.id}
                  onClick={onClickItem.bind(this, item)}
                  className={classNames(
                    'cursor-pointer hstack gap-2 me-4',
                    classs.item,
                  )}
                  style={{ width: 140 }}
                >
                  <span className="text-start flex-grow-1">{item.name}</span>
                  <i className="bi bi-star"></i>
                </div>
              );
            })}
          </div>
        </div>
        <div className={classNames('overflow-hidden', classs.marginLeft)}>
          <div>
            <div ref={myHomepageRef} className="mb-4 text-secondary">
              <i className="bi bi-signpost me-2"></i>
              {translatedFields.myProfile}
            </div>
            <div className="card mb-4">
              <div className="card-body">
                <div className="row row-cols-1 g-4">
                  <div className="col">
                    <div className="hstack gap-4" style={{ height: 200 }}>
                      <div>
                        <Image
                          className="rounded-circle img-thumbnail object-fit-contain"
                          src={
                            getUserAvatar(source.userDetails.user, metadata)
                              .largeAvatarUrl
                          }
                          width={200}
                          height={200}
                          alt="avatar"
                          placeholder="blur"
                          blurDataURL={env.APP_BLUR_DATA_URL}
                        />
                      </div>
                      <div className="h-100">
                        <div className="h3 mt-2">
                          {source.userDetails.user.alias}
                        </div>
                        {roles.length > 0 && (
                          <div className="hstack mt-4 cursor-default">
                            <i className="bi bi-person-badge me-2"></i>
                            {roles.map((item, index) => {
                              return (
                                <div key={item.id}>
                                  <span>{item.name}</span>
                                  {index !== roles.length - 1 && (
                                    <span className="mx-2">/</span>
                                  )}
                                </div>
                              );
                            })}
                          </div>
                        )}

                        {source.userDetails.user.details
                          .personalizedSignature && (
                          <div className="my-4">
                            <i className="bi bi-balloon-fill me-2"></i>
                            {
                              source.userDetails.user.details
                                .personalizedSignature
                            }
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                  <div className="col">
                    <hr className="text-secondary" />
                  </div>
                  <div className="col">
                    <div className="row row-cols-2 g-4 mb-3">
                      <div className="col-4">
                        <div className="h5">
                          <i className="bi bi-person-rolodex me-2"></i>
                          {translatedFields.contactInformation}
                        </div>

                        {source.userDetails.user.details.contacts &&
                        source.userDetails.user.details.contacts.length > 0 ? (
                          <div className="vstack gap-2 mt-4">
                            {source.userDetails.user.details.contacts.map(
                              (item) => {
                                return (
                                  <div key={item.id}>
                                    <span className="me-2">{item.key}</span>
                                    {item.val.includes('@') &&
                                    item.val.includes('.') ? (
                                      <a
                                        className="link-dark text-decoration-none text-decoration-underline-hover"
                                        href={`mailto:${item.val}`}
                                      >
                                        {item.val}
                                      </a>
                                    ) : (
                                      <>
                                        {isHttpOrHttps(item.val) ? (
                                          <a
                                            className="link-dark text-decoration-none text-decoration-underline-hover"
                                            href={item.val}
                                          >
                                            {item.val}
                                          </a>
                                        ) : (
                                          <span>{item.val}</span>
                                        )}
                                      </>
                                    )}
                                  </div>
                                );
                              },
                            )}
                          </div>
                        ) : (
                          <div className="mt-4 text-secondary">
                            {translatedFields.noInformation}
                          </div>
                        )}
                      </div>
                      <div className="col-8">
                        <div className="h5">
                          <i className="bi bi-person-lines-fill me-2"></i>
                          {translatedFields.aboutMe}
                        </div>

                        {source.userDetails.user.details.about ? (
                          <div className="mt-4">
                            <div
                              dangerouslySetInnerHTML={{
                                __html: source.userDetails.user.details.about,
                              }}
                            />
                          </div>
                        ) : (
                          <div className="mt-4 text-secondary">
                            {translatedFields.noInformation}
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>

          {isMyHomePage && (
            <>
              <div className="mt-5">
                <div ref={myUpdateBasicInfoRef} className="mb-4 text-secondary">
                  <i className="bi bi-signpost me-2"></i>
                  {translatedFields.editProfile}
                </div>
                <div className="mb-4 card">
                  <div className="card-body">
                    <UpdateBasicInfoUserIdPage />
                  </div>
                </div>
              </div>

              <div className="mt-5">
                <div ref={myUpdatePasswordRef} className="mb-4 text-secondary">
                  <i className="bi bi-signpost me-2"></i>
                  {translatedFields.changePassword}
                </div>
                <div className="mb-4 card">
                  <div className="card-body">
                    <UpdatePasswordUserIdPage />
                  </div>
                </div>
              </div>
            </>
          )}

          <div className="mt-5">
            <div ref={myPostRef} className="mb-4 text-secondary">
              <i className="bi bi-signpost me-2"></i>
              {translatedFields.myPosts}
            </div>
            <div className="mb-4 row row-cols-1 g-4">
              {pages.map((item) => {
                return (
                  <div key={item.id} className="col">
                    <div className="card text-center">
                      <div className="card-body">
                        <div className="card-title">
                          <PostName
                            item={item}
                            isFwSemibold={false}
                            isJustifyContentCenter
                          />
                        </div>

                        <PostOverview item={item} bodClassName="my-4" />

                        <PostReadMoreBtn
                          item={item}
                          isEdit={
                            isMyHomePage &&
                            source.userDetails.user.id === item.createdBy
                          }
                        />
                      </div>
                      <div className="card-footer">
                        <PostTime item={item} />
                      </div>
                    </div>
                  </div>
                );
              })}

              {pages.length === 0 && (
                <div className="col">
                  <div className="card text-center cursor-default">
                    <div className="card-body">
                      <div className="card-text text-secondary">
                        {translatedFields.noArticle}
                      </div>
                    </div>
                  </div>
                </div>
              )}
            </div>

            <LoadMoreBtn
              onClickLoadMore={onClickLoadMore}
              isLoading={clientQueryUserDetailsQuery.isLoading}
            />
          </div>

          {isMyHomePage && (
            <>
              {queryPostFavouritesQuery.data && (
                <div className="mt-5">
                  <div ref={myCollectionRef} className="mb-4 text-secondary">
                    <i className="bi bi-signpost me-2"></i>
                    {translatedFields.myFavorites}
                  </div>
                  <div className="mb-4 row row-cols-1 g-4">
                    {queryPostFavouritesQuery.data.length === 0 && (
                      <div className="col">
                        <div className="card text-center cursor-default">
                          <div className="card-body">
                            <div className="card-text text-secondary">
                              {translatedFields.noFavorite}
                            </div>
                          </div>
                        </div>
                      </div>
                    )}

                    {queryPostFavouritesQuery.data.map((item) => {
                      return (
                        <div key={item.id} className="col">
                          <div className="card text-center">
                            <div className="card-body">
                              <h5 className="card-title">
                                <Link
                                  className="link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
                                  href={`/posts/${item.postId}`}
                                >
                                  {item.name}
                                </Link>
                              </h5>

                              <Link
                                className="btn btn-primary mt-4"
                                href={`/posts/${item.postId}`}
                              >
                                <i className="bi bi-book me-2"></i>
                                {translatedFields.readMore}
                              </Link>
                            </div>
                            <div className="card-footer text-secondary cursor-default">
                              <time dateTime={item.updatedOn}>
                                {toRelativeTime(item.updatedOn)}
                              </time>
                            </div>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                </div>
              )}

              {queryPostFavouritesQuery.isLoading && (
                <div className="mt-5">
                  <div ref={myCollectionRef} className="mb-4 text-secondary">
                    <i className="bi bi-signpost me-2"></i>
                    {translatedFields.myFavorites}
                  </div>
                  <div className="mb-4 row row-cols-1 g-4">
                    <div className="col">
                      <div className="card text-center cursor-default">
                        <div className="card-body">
                          <div className="hstack gap-2 align-items-center justify-content-center">
                            <Spinner classs="me-2" />
                            <div className="card-text text-secondary">
                              Loading...
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              )}
            </>
          )}

          <div className="mt-5">
            <div ref={mySectionRef} className="mb-4 text-secondary">
              <i className="bi bi-signpost me-2"></i>
              {translatedFields.relatedContent}
            </div>
            <div className="mb-4 row row-cols-5 g-4">
              {source.userDetails.sections.map((item) => {
                return (
                  <div key={item.id} className="col">
                    <div className="card">
                      <div className="list-group list-group-flush text-center">
                        <Link
                          href={`/users/${source.userDetails.user.id}?sid=${item.id}`}
                          className={classNames(
                            'list-group-item list-group-item-action py-3',
                            {
                              active:
                                source.queryParams.sectionId === item.id + '',
                            },
                          )}
                        >
                          {item.name}
                        </Link>
                      </div>
                    </div>
                  </div>
                );
              })}

              <div className="col">
                <div className="card">
                  <div className="list-group list-group-flush text-center">
                    <Link
                      href={`/users/${source.userDetails.user.id}`}
                      className={classNames(
                        'list-group-item list-group-item-action py-3',
                        {
                          disabled: source.userDetails.sections.length === 0,
                        },
                      )}
                    >
                      {translatedFields.all}
                    </Link>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div className="mt-5">
            <div ref={myTagRef} className="mb-4 text-secondary">
              <i className="bi bi-signpost me-2"></i>
              {translatedFields.relatedTags}
            </div>
            <div className="mb-4 row row-cols-6 g-4">
              {source.userDetails.tags.map((item) => {
                return (
                  <div key={item.id} className="col">
                    <div className="card">
                      <div className="list-group list-group-flush text-center">
                        <Link
                          href={`/users/${source.userDetails.user.id}?tid=${item.id}`}
                          className={classNames(
                            'list-group-item list-group-item-action',
                            {
                              active: source.queryParams.tagId === item.id + '',
                            },
                          )}
                        >
                          {item.name}
                        </Link>
                      </div>
                    </div>
                  </div>
                );
              })}

              <div className="col">
                <div className="card">
                  <div className="list-group list-group-flush text-center">
                    <Link
                      href={`/users/${source.userDetails.user.id}`}
                      className={classNames(
                        'list-group-item list-group-item-action',
                        {
                          disabled: source.userDetails.tags.length === 0,
                        },
                      )}
                    >
                      {translatedFields.all}
                    </Link>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <div className="mt-5">
            <div ref={myStatisticRef} className="mb-4 text-secondary">
              <i className="bi bi-signpost me-2"></i>
              {translatedFields.relatedStatistics}
            </div>
            <div className="mb-4 row row-cols-6 g-4">
              <div className="col">
                <div className="card rounded-5">
                  <div className="card-body">
                    <div className="mb-1">
                      <i className="bi bi-bar-chart fs-5"></i>
                    </div>
                    <p className="card-text">
                      {translatedFields.numberOfContents}&nbsp;
                      {formatCount(source.userDetails.user.statistic.sections)}
                    </p>
                  </div>
                </div>
              </div>

              <div className="col">
                <div className="card rounded-5">
                  <div className="card-body">
                    <div className="mb-1">
                      <i className="bi bi-bar-chart fs-5"></i>
                    </div>
                    <p className="card-text">
                      {translatedFields.numberOfTags}&nbsp;
                      {formatCount(source.userDetails.user.statistic.tags)}
                    </p>
                  </div>
                </div>
              </div>

              <div className="col">
                <div className="card rounded-5">
                  <div className="card-body">
                    <div className="mb-1">
                      <i className="bi bi-bar-chart fs-5"></i>
                    </div>
                    <p className="card-text">
                      {translatedFields.numberOfPosts}&nbsp;
                      {formatCount(source.userDetails.user.statistic.posts)}
                    </p>
                  </div>
                </div>
              </div>

              <div className="col">
                <div className="card rounded-5">
                  <div className="card-body">
                    <div className="mb-1">
                      <i className="bi bi-bar-chart fs-5"></i>
                    </div>
                    <p className="card-text">
                      {translatedFields.numberOfComments}&nbsp;
                      {formatCount(source.userDetails.user.statistic.comments)}
                    </p>
                  </div>
                </div>
              </div>

              <div className="col">
                <div className="card rounded-5">
                  <div className="card-body">
                    <div className="mb-1">
                      <i className="bi bi-bar-chart fs-5"></i>
                    </div>
                    <p className="card-text">
                      {translatedFields.numberOfReplies}&nbsp;
                      {formatCount(source.userDetails.user.statistic.replies)}
                    </p>
                  </div>
                </div>
              </div>

              <div className="col">
                <div className="card rounded-5">
                  <div className="card-body">
                    <div className="mb-1">
                      <i className="bi bi-bar-chart fs-5"></i>
                    </div>
                    <p className="card-text">
                      {translatedFields.numberOfViews}&nbsp;
                      {formatCount(source.userDetails.user.statistic.views)}
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </PcBox>
      <UserIdH5Page />
    </UserIdPageContext.Provider>
  );
}

const LoadMoreBtn = ({
  onClickLoadMore,
  isLoading,
}: {
  onClickLoadMore: () => void;
  isLoading: boolean;
}) => {
  return (
    <div className="row mx-0">
      <div className="col px-0">
        <button
          onClick={onClickLoadMore}
          disabled={isLoading}
          type="button"
          className="btn rounded-pill text-secondary-emphasis w-100"
        >
          {isLoading ? <Spinner /> : <i className="bi bi-three-dots"></i>}
        </button>
      </div>
    </div>
  );
};
